package com.xiaoshuidi.cloud.module.member.service.point;

import cn.hutool.core.date.LocalDateTimeUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.xiaoshuidi.cloud.framework.common.exception.ServiceException;
import com.xiaoshuidi.cloud.framework.common.exception.enums.GlobalErrorCodeConstants;
import com.xiaoshuidi.cloud.framework.common.pojo.CommonResult;
import com.xiaoshuidi.cloud.framework.common.pojo.PageResult;
import com.xiaoshuidi.cloud.framework.mybatis.core.util.MyBatisUtils;
import com.xiaoshuidi.cloud.framework.redis.lock.DistributeLock;
import com.xiaoshuidi.cloud.module.member.constant.Constant;
import com.xiaoshuidi.cloud.module.member.controller.admin.point.vo.MemberPointsChangeVo;
import com.xiaoshuidi.cloud.module.member.controller.admin.point.vo.MemberPointsPageReqVo;
import com.xiaoshuidi.cloud.module.member.controller.admin.point.vo.MemberPointsPageRespVo;
import com.xiaoshuidi.cloud.module.member.controller.app.point.vo.*;
import com.xiaoshuidi.cloud.module.member.convert.auth.AuthConvert;
import com.xiaoshuidi.cloud.module.member.convert.point.PointsConvert;
import com.xiaoshuidi.cloud.module.member.enums.ErrorCodeConstants;
import com.xiaoshuidi.cloud.module.member.enums.point.*;
import com.xiaoshuidi.cloud.module.member.mapper.point.MemberPointsMapper;
import com.xiaoshuidi.cloud.module.member.mapper.point.MemberPointsRecordMapper;
import com.xiaoshuidi.cloud.module.member.pojo.point.MemberPointsEntity;
import com.xiaoshuidi.cloud.module.member.pojo.point.MemberPointsRecordEntity;
import com.xiaoshuidi.cloud.module.member.pojo.user.MemberUser;
import com.xiaoshuidi.cloud.module.member.service.user.MemberUserService;
import com.xiaoshuidi.cloud.module.system.api.sms.SmsCodeApi;
import com.xiaoshuidi.cloud.module.system.api.sms.dto.code.SmsCodeSendReqDTO;
import com.xiaoshuidi.cloud.module.system.api.sms.dto.code.SmsCodeUseReqDTO;
import com.xiaoshuidi.cloud.module.system.enums.sms.SmsSceneEnum;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicInteger;

import static com.xiaoshuidi.cloud.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.xiaoshuidi.cloud.framework.common.util.servlet.ServletUtils.getClientIP;
import static com.xiaoshuidi.cloud.module.member.enums.ErrorCodeConstants.USER_ID_NOT_NULL;


/**
 * @author neil
 * @version generator
 * @description 租客积分service层
 * @date 2022-12-14 18:08:07
 */
@Service
@Slf4j
public class MemberPointsService {
    @Autowired
    MemberPointsRecordService recordService;
    @Autowired
    MemberPointsMapper tenantPointsMapper;

    @Autowired
    MemberPointsRecordMapper memberPointsRecordMapper;
    @Autowired
    MemberUserService memberUserService;
    @Resource
    private SmsCodeApi smsCodeApi;

    /**
     * 列表查询
     */
    public List<TenantPointsDto> list(TenantPointsParamDto paramDto, Integer page, Integer size) throws Exception {
        if (Objects.isNull(paramDto) || Objects.isNull(page) || Objects.isNull(size)) {
            return Collections.emptyList();
        }
        List<TenantPointsDto> dtoList = tenantPointsMapper.list(paramDto, (page - 1) * size, size);
        if (Objects.isNull(dtoList) || dtoList.isEmpty()) {
            return Collections.emptyList();
        }
        return dtoList;
    }


    /**
     * 根据tenantUserId查询积分详情
     *
     * @param tenantUserId
     * @return
     * @author Morty.Wang
     * @date 2022年12月20日 上午10:58:27
     */
    public TenantPointsVo getByTenantUserId(Long tenantUserId) {
        String key = Constant.POINT_ID_KEY.concat(tenantUserId.toString());
        try (DistributeLock lock = DistributeLock.getLock(key)) {
            if (lock.tryLock()) {
                TenantPointsVo vo = tenantPointsMapper.getTenantPointsVoByUserId(tenantUserId);
                if (vo == null) {
                    MemberPointsEntity entity = new MemberPointsEntity();
                    entity.setTenantUserId(tenantUserId);
                    entity.setRank(PointRankEnums.LV1.getRank());
                    entity.setAvailablePoints(0l);
                    entity.setGrowthValue(0l);
                    tenantPointsMapper.insert(entity);
                    return PointsConvert.INSTANCE.convertToVo(entity);
                }
                return vo;
            }
        }
        return null;
    }

    /**
     * 积分变动
     *
     * @param dto      原始积分dto
     * @param paramDto 积分变动入参param
     * @return
     * @author neil
     * @date 2022-12-26 15:38
     */
    public TenantPointsDto change(TenantPointsDto dto, TenantPointsChangeParamDto paramDto) {
        MemberPointsRecordEntity entityDto = new MemberPointsRecordEntity();
        entityDto.setRecordNo(paramDto.getRecordNo());
        entityDto.setTenantUserId(dto.getTenantUserId());
        entityDto.setChangeType(paramDto.getChangeType());
        entityDto.setRecordType(paramDto.getRecordType());
        entityDto.setBeforeChangePoints(dto.getAvailablePoints());
        entityDto.setChangeValue(paramDto.getChangeValue());
        entityDto.setChangeValueType(paramDto.getChangeValueType());
        entityDto.setRemark(paramDto.getRemark());
        //积分增减
        if (PointChangeValueEnums.ADD.value() == paramDto.getChangeValueType() && paramDto.getChangeValue() > 0l) {
            PointChangePO po = new PointChangePO(0l, 0);
            po = calculatePoints(dto.getGrowthValue(), paramDto.getChangeValue(), po);
            //新增积分变动修改
            dto.setGrowthValue(dto.getGrowthValue() + po.getPoints());
            //积分record记录，包含变动的+升级赠送
            entityDto.setAfterChangePoints(dto.getAvailablePoints() + paramDto.getChangeValue());
            recordService.insert(entityDto);
            Long temp = dto.getAvailablePoints() + paramDto.getChangeValue();
            for (int i = 0; i < po.getLvs(); i++) {
                MemberPointsRecordEntity lvDto = new MemberPointsRecordEntity();
                lvDto.setBeforeChangePoints(temp);
                temp = temp + PointEnums.STEP.value();
                lvDto.setRecordNo("LV" + paramDto.getRecordNo());
                lvDto.setTenantUserId(dto.getTenantUserId());
                lvDto.setChangeType(PointChangeEnums.AUTO.value());
                lvDto.setChangeValue(PointEnums.STEP.value());
                lvDto.setRecordType(PointRecordEnums.UPGRADE.value());
                lvDto.setChangeValueType(PointChangeValueEnums.ADD.value());
                lvDto.setRemark("升级赠积分");
                lvDto.setAfterChangePoints(temp);
                recordService.insert(lvDto);
            }
            //最后处理积分新增总量
            dto.setAvailablePoints(dto.getAvailablePoints() + po.getPoints());
            dto.setRank(PointRankEnums.getInstance(dto.getGrowthValue()).getRank());
            MemberPointsEntity entity = PointsConvert.INSTANCE.convert(dto);
            tenantPointsMapper.insert(entity);
        }
        if (PointChangeValueEnums.REDUCE.value() == paramDto.getChangeValueType()) {
            dto.setAvailablePoints(dto.getAvailablePoints() - paramDto.getChangeValue());
            entityDto.setAfterChangePoints(dto.getAvailablePoints());
            MemberPointsEntity entity = PointsConvert.INSTANCE.convert(dto);
            tenantPointsMapper.insert(entity);
        }
        return dto;
    }

    /**
     * 积分回退==积分增加
     *
     * @param dto       原始积分dto
     * @param recordDto 积分记录入参dto
     * @return
     * @author neil
     * @date 2023-1-10 15:38
     */
    public TenantPointsDto refund(TenantPointsDto dto, TenantPointsRecordDto recordDto) {
        MemberPointsRecordEntity entityDto = new MemberPointsRecordEntity();
        entityDto.setRecordNo("RE" + recordDto.getRecordNo());
        entityDto.setTenantUserId(dto.getTenantUserId());
        entityDto.setChangeType(PointChangeEnums.AUTO.value());
        entityDto.setBeforeChangePoints(dto.getAvailablePoints());
        entityDto.setChangeValue(recordDto.getChangeValue());
        entityDto.setRecordType(PointRecordEnums.REFUND.value());
        entityDto.setChangeValueType(PointChangeValueEnums.ADD.value());
        entityDto.setRemark("积分退款");
        entityDto.setAfterChangePoints(dto.getAvailablePoints() + recordDto.getChangeValue());
        recordService.insert(entityDto);
        //最后处理积分信息
        dto.setAvailablePoints(dto.getAvailablePoints() + recordDto.getChangeValue());
        MemberPointsEntity entity = PointsConvert.INSTANCE.convert(dto);
        tenantPointsMapper.insert(entity);
        return dto;
    }


    /**
     * 积分计算逻辑 每升一级加2000积分
     *
     * @param growth 原始成长值
     * @param value  本次积分增量
     * @param po     总增量，升级次数
     * @return
     * @author neil
     * @date 2022-12-26 15:27:45
     */
    private PointChangePO calculatePoints(Long growth, Long value, PointChangePO po) {
        //单次增量累加
        po.setPoints(po.getPoints() + value);
        //判断当前等级加上value后是否满足升级
        Integer dlv = PointLvEnums.getInstance(growth + value).getLv() - PointLvEnums.getInstance(growth).getLv();
        if (dlv > 0) {
            po.setLvs(po.getLvs() + dlv);
            //重置成长值
            growth = growth + value + (dlv * PointEnums.STEP.value());
            return calculatePoints(growth, (dlv * PointEnums.STEP.value()), po);
        }
        return po;
    }

    /**
     * 查询参数设置
     *
     * @param params
     * @author neil
     * @date 2023-1-5 15:27:45
     */
    private LambdaQueryWrapper<MemberPointsEntity> getWrapper(Map<String, Object> params) {
        LambdaQueryWrapper<MemberPointsEntity> wrapper = new LambdaQueryWrapper<>();
        if (null != params.get("tenantUserId")) {
            String tenantUserId = String.valueOf(params.get("tenantUserId"));
            wrapper.eq(StringUtils.isNotBlank(tenantUserId), MemberPointsEntity::getTenantUserId, tenantUserId);
        }
        //最小值
        if (null != params.get("queryMin")) {
            String queryMin = (String) params.get("queryMin");
            wrapper.ge(StringUtils.isNotBlank(queryMin), MemberPointsEntity::getAvailablePoints, queryMin);
        }
        //最大值
        if (null != params.get("queryMax")) {
            String queryMax = (String) params.get("queryMax");
            wrapper.le(StringUtils.isNotBlank(queryMax), MemberPointsEntity::getAvailablePoints, queryMax);
        }
        //更新结束时间
        if (null != params.get("queryEndTime")) {
            String queryEndTime = (String) params.get("queryEndTime");
            wrapper.le(StringUtils.isNotBlank(queryEndTime), MemberPointsEntity::getUpdateTime, queryEndTime);
        }
        //更新开始时间
        if (null != params.get("queryBeginTime")) {
            String queryBeginTime = (String) params.get("queryBeginTime");
            wrapper.ge(StringUtils.isNotBlank(queryBeginTime), MemberPointsEntity::getUpdateTime, queryBeginTime);
        }
        //手机号
        if (null != params.get("tenantUserIds")) {
            List<Long> tenantUserIds = (List) params.get("tenantUserIds");
            if (tenantUserIds.size() > 0) {
                wrapper.in(true, MemberPointsEntity::getTenantUserId, tenantUserIds);
            }
        }
        //等级
        if (null != params.get("rank")) {
            String rank = (String) params.get("rank");
            wrapper.eq(StringUtils.isNotBlank(rank), MemberPointsEntity::getRank, rank);
        }
        return wrapper;
    }

    public List<TenantPointsDto> list(Map<String, Object> params) throws Exception {
        List<MemberPointsEntity> entity = tenantPointsMapper.selectList(getWrapper(params));
        if (entity == null) {
            throw new Exception("数据不存在");
        }
        return PointsConvert.INSTANCE.convert(entity);
    }

    public PageResult<MemberPointsPageRespVo> getMemberPointsPage(MemberPointsPageReqVo reqVo) {
        if (StringUtils.isNotBlank(reqVo.getPhone())) {
            //手机号查询租客
            MemberUser user = memberUserService.getUserByMobile(reqVo.getPhone());
            if (user != null) {
                reqVo.setTenantUserId(user.getId());
            }
        }
        IPage<MemberPointsPageReqVo> page = MyBatisUtils.buildPage(reqVo);
        List<MemberPointsPageRespVo> list = tenantPointsMapper.selectTenantPointsPage(page, reqVo);
        PageResult<MemberPointsPageRespVo> pageResult = new PageResult(list, page.getTotal());
        pageResult.setList(list);
        return pageResult;
    }

    public List<MemberPointsPageRespVo> exportTenantPoints(MemberPointsPageReqVo reqVo) {
        if (StringUtils.isNotBlank(reqVo.getPhone())) {
            //手机号查询租客
            MemberUser user = memberUserService.getUserByMobile(reqVo.getPhone());
            if (user != null) {
                reqVo.setTenantUserId(user.getId());
            }
        }
        List<MemberPointsPageRespVo> list = tenantPointsMapper.selectTenantPointsPage(reqVo);
        AtomicInteger i = new AtomicInteger(1);
        for (MemberPointsPageRespVo vo : list) {
            vo.setId(i.longValue());
            i.incrementAndGet();
            vo.setUpdateDateTime(LocalDateTimeUtil.format(vo.getUpdateTime(), "yyyy-MM-dd HH:mm:ss"));
        }
        return list;
    }

    @Transactional
    public void plusTenantPoints(MemberPointsChangeVo reqVo) {
        reqVo.setChangeType(0);
        this.changeTenantPoints(reqVo, PointRecordEnums.HAND);
    }

    @Transactional
    public void minusTenantPoints(MemberPointsChangeVo reqVo) {
        //分值取反
        reqVo.setPoint(BigDecimal.valueOf(reqVo.getPoint()).negate().intValue());
        reqVo.setChangeType(0);
        this.deduceTenantPoints(reqVo, PointRecordEnums.HAND);
    }

    public void deduceTenantPoints(MemberPointsChangeVo reqVo, PointRecordEnums enu) {
        if (reqVo.getId() == null) {
            throw exception(USER_ID_NOT_NULL);
        }
        //并发锁
        String key = Constant.POINT_ID_KEY.concat(reqVo.getId().toString());
        try (DistributeLock lock = DistributeLock.getLock(key)) {
            if (lock.tryLock()) {
                //租客积分表变更
                MemberPointsEntity entity = tenantPointsMapper.selectById(reqVo.getId());
                Integer oldRank = entity.getRank();
                if (entity != null) {
                    Long points = new Long(entity.getAvailablePoints());
                    entity.setAvailablePoints(entity.getAvailablePoints() + reqVo.getPoint());
                    //扣减积分成长值等级不变，积分修改
                    tenantPointsMapper.updateById(entity);

                    //明细表加记录
                    MemberPointsRecordEntity record = new MemberPointsRecordEntity();
                    record.setTenantUserId(entity.getTenantUserId());
                    record.setRecordNo(StringUtils.isNotBlank(reqVo.getRecordNo()) ? reqVo.getRecordNo() : String.valueOf(System.currentTimeMillis()));
                    record.setOldRecordNo(reqVo.getOldRecordNo());
                    record.setRecordType(enu.value);
                    record.setChangeType(reqVo.getChangeType());
                    record.setChangeValueType(reqVo.getPoint() > 0 ? PointChangeValueEnums.ADD.value() : PointChangeValueEnums.REDUCE.value());
                    record.setChangeValue(Long.valueOf(Math.abs(reqVo.getPoint())));
                    record.setBeforeChangePoints(points);
                    record.setAfterChangePoints(entity.getAvailablePoints());
                    record.setChangePoint(Long.valueOf(Math.abs(reqVo.getPoint())));
                    record.setRemark(reqVo.getRemark());
                    recordService.insert(record);

                }
            }
        }
    }

    @Transactional(rollbackFor = Exception.class)
    public void changeTenantPoints(MemberPointsChangeVo reqVo, PointRecordEnums enu) {
        if (reqVo.getId() == null) {
            throw exception(USER_ID_NOT_NULL);
        }
        //并发锁
        String key = Constant.POINT_ID_KEY.concat(reqVo.getId().toString());
        try (DistributeLock lock = DistributeLock.getLock(key)) {
            if (lock.tryLock()) {
                //租客积分表变更
                MemberPointsEntity entity = tenantPointsMapper.selectById(reqVo.getId());
                Integer oldRank = entity.getRank();
                if (entity != null) {
                    Long points = new Long(entity.getAvailablePoints());
                    entity.setAvailablePoints(entity.getAvailablePoints() + reqVo.getPoint());
                    entity.setGrowthValue(entity.getGrowthValue() + reqVo.getPoint());
                    int growthValueNum = entity.getGrowthValue().intValue();
                    //根据积分多少，算出会员目前的等级
                    calRank(entity, growthValueNum);

                    //比较下每升级一个等级会员得到对应2000积分
                    Integer rank = entity.getRank();
                    if (rank.intValue() != oldRank.intValue()) {
                        //比较等级升级级数
                        int levelPoints = (rank.intValue() - oldRank.intValue()) * 2000;
                        entity.setAvailablePoints(entity.getAvailablePoints() + levelPoints);
                        entity.setGrowthValue(entity.getGrowthValue() + levelPoints);
                        int finalGrowth = entity.getGrowthValue().intValue();
                        calRank(entity, finalGrowth);
                    }
                    tenantPointsMapper.updateById(entity);

                    //明细表加记录
                    MemberPointsRecordEntity record = new MemberPointsRecordEntity();
                    record.setTenantUserId(entity.getTenantUserId());
                    record.setRecordNo(StringUtils.isNotBlank(reqVo.getRecordNo()) ? reqVo.getRecordNo() : String.valueOf(System.currentTimeMillis()));
                    record.setRecordType(enu.value);
                    record.setChangeType(reqVo.getChangeType());
                    record.setChangeValueType(reqVo.getPoint() > 0 ? PointChangeValueEnums.ADD.value() : PointChangeValueEnums.REDUCE.value());
                    record.setChangeValue(Long.valueOf(entity.getAvailablePoints() - points));
                    record.setChangePoint(reqVo.getPoint().longValue());
                    record.setBeforeChangePoints(points);
                    record.setAfterChangePoints(entity.getAvailablePoints());
                    record.setRemark(reqVo.getRemark());
                    recordService.insert(record);

                }
            }
        }
    }


    @Transactional(rollbackFor = Exception.class)
    public void refundTenantPoints(MemberPointsChangeVo reqVo, PointRecordEnums enu) {
        if (reqVo.getId() == null) {
            throw exception(USER_ID_NOT_NULL);
        }
        //并发锁
        String key = Constant.POINT_ID_KEY.concat(reqVo.getId().toString());
        try (DistributeLock lock = DistributeLock.getLock(key)) {
            if (lock.tryLock()) {
                //租客积分表变更
                MemberPointsEntity entity = tenantPointsMapper.selectById(reqVo.getId());
                Integer oldRank = entity.getRank();
                if (entity != null) {
                    Long points = new Long(entity.getAvailablePoints());
                    entity.setAvailablePoints(entity.getAvailablePoints() + reqVo.getPoint());
                    entity.setGrowthValue(entity.getGrowthValue() + reqVo.getPoint());
                    int growthValueNum = entity.getGrowthValue().intValue();
                    //根据积分多少，算出会员目前的等级
                    calRank(entity, growthValueNum);
                    tenantPointsMapper.updateById(entity);

                    //明细表加记录
                    MemberPointsRecordEntity record = new MemberPointsRecordEntity();
                    record.setTenantUserId(entity.getTenantUserId());
                    record.setRecordNo(StringUtils.isNotBlank(reqVo.getRecordNo()) ? reqVo.getRecordNo() : String.valueOf(System.currentTimeMillis()));
                    record.setRecordType(enu.value);
                    record.setChangeType(reqVo.getChangeType());
                    record.setChangeValueType(reqVo.getPoint() > 0 ? PointChangeValueEnums.ADD.value() : PointChangeValueEnums.REDUCE.value());
                    record.setChangeValue(Long.valueOf(entity.getAvailablePoints() - points));
                    record.setChangePoint(reqVo.getPoint().longValue());
                    record.setBeforeChangePoints(points);
                    record.setAfterChangePoints(entity.getAvailablePoints());
                    record.setRemark(reqVo.getRemark());
                    recordService.insert(record);

                }
            }
        }
    }

    private void calRank(MemberPointsEntity entity, int growthNum) {
        //1.LV1 9999积分以下
        if (growthNum <= 9999) {
            entity.setRank(1);
        } else if (growthNum >= 10000 && growthNum <= 19999) {
            //LV2 10000-19999积分
            entity.setRank(2);
        } else if (growthNum >= 20000 && growthNum <= 29999) {
            //LV3 20000-29999积分
            entity.setRank(3);
        } else if (growthNum >= 30000 && growthNum <= 39999) {
            //LV4 30000-39999积分
            entity.setRank(4);
        } else if (growthNum >= 40000 && growthNum <= 49999) {
            //LV5 40000-49999积分
            entity.setRank(5);
        } else if (growthNum >= 50000 && growthNum <= 59999) {
            //LV6 50000-59999积分
            entity.setRank(6);
        } else if (growthNum >= 60000) {
            //LV7 60000以上
            entity.setRank(7);
        }
    }

    @Transactional
    public void memberPointsChange(Long memberId, Integer point, PointRecordEnums enums, String remarks) {
        TenantPointsVo entity = this.getByTenantUserId(memberId);
        MemberPointsChangeVo vo = new MemberPointsChangeVo();
        vo.setId(entity.getId());
        vo.setPoint(point);
        vo.setRemark(remarks);
        vo.setChangeType(1);
        this.changeTenantPoints(vo, enums);
    }

    /**
     * 积分商城增加或者扣减积分
     *
     * @param reqVo
     * @return
     */
    public Boolean modifyTenantPoints(MemberPointsChangeVo reqVo) {
        if (Objects.isNull(reqVo) || Objects.isNull(reqVo.getType()) || Objects.isNull(reqVo.getId())
                || Objects.isNull(reqVo.getPoint()) || StringUtils.isEmpty(reqVo.getRemark())
                || Objects.isNull(reqVo.getType()) || Objects.isNull(reqVo.getChangeType()) || StringUtils.isEmpty(reqVo.getRecordNo())) {
            log.error("modifyTenantPoints入参有空值。。。。");
            return false;
        }
        if (reqVo.getChangeType().intValue() != PointSendTypeEnum.MALL.getCode().intValue()) {
            log.error("modifyTenantPoints入参changeType不为商城来源。。。。");
            return false;
        }
        //如果是增加积分
        if (reqVo.getType().intValue() == PointChangeValueEnums.ADD.value()) {
            this.changeTenantPoints(reqVo, PointRecordEnums.MALL);
        } else if (reqVo.getType().intValue() == PointChangeValueEnums.REDUCE.value()) {
            reqVo.setPoint(BigDecimal.valueOf(reqVo.getPoint()).negate().intValue());
            this.deduceTenantPoints(reqVo, PointRecordEnums.MALL);
        }
        return true;
    }

    /**
     * 积分退费
     *
     * @param reqVo
     * @return
     */
    public Boolean refundTenantPoints(PointRefund reqVo) {
        if (Objects.isNull(reqVo) || Objects.isNull(reqVo.getId())
                || Objects.isNull(reqVo.getPoint()) || StringUtils.isEmpty(reqVo.getRemark())
                || StringUtils.isEmpty(reqVo.getOldRecordNo()) || StringUtils.isEmpty(reqVo.getRecordNo())) {
            log.error("refundTenantPoints入参有空值。。。。");
            return false;
        }
        try {
            //查询原流水号的交易记录
            LambdaQueryWrapper<MemberPointsRecordEntity> wrapper = new LambdaQueryWrapper<MemberPointsRecordEntity>()
                    .eq(MemberPointsRecordEntity::getRecordNo, reqVo.getOldRecordNo())
                    .eq(MemberPointsRecordEntity::getTenantUserId, reqVo.getUserId());
            MemberPointsRecordEntity oldRecord = memberPointsRecordMapper.selectOne(wrapper);
            if (Objects.isNull(oldRecord)) {
                log.error("根据退费原交易号没有查询到记录。。。。");
                return false;
            }

            //查询针对原交易流水号，累计的退费总和
            Long totalPoint = memberPointsRecordMapper.getTotalPointsByOldRecord(reqVo.getOldRecordNo(), reqVo.getUserId());
            //如果加上此次退费已超过原交易号的总扣费的或者退费直接超过原交易号的总扣费的，参数异常
            //1
            if (oldRecord.getChangePoint().intValue() < reqVo.getPoint().intValue()) {
                log.error("退费积分超过原交易号的总扣费");
                return false;
            }
            //2
            if (!ObjectUtils.isEmpty(totalPoint) && (totalPoint.intValue() + reqVo.getPoint().intValue() > oldRecord.getChangePoint().intValue())) {
                log.error("退费积分总和已超过原交易号的总扣费");
                return false;
            }
            //进行退费
            MemberPointsChangeVo memberPointsChangeVo = new MemberPointsChangeVo();
            memberPointsChangeVo.setId(reqVo.getId())
                    .setRemark(reqVo.getRemark())
                    .setRecordNo(reqVo.getRecordNo())
                    .setChangeType(PointSendTypeEnum.MALL.getCode())
                    .setType(PointTypeEnum.PLUS.getCode())
                    .setOldRecordNo(reqVo.getOldRecordNo())
                    .setPoint(reqVo.getPoint());
            this.refundTenantPoints(memberPointsChangeVo, PointRecordEnums.MALL);
        } catch (Exception e) {
            log.error("根据原商城流水号查询积分记录有异常", e);
            return false;
        }

        return true;
    }

    public void updateUserId(Long oldUserId, Long userId) {
        //查询出新旧积分主表
        TenantPointsVo oldPoint = this.getByTenantUserId(oldUserId);
        TenantPointsVo point = this.getByTenantUserId(userId);
        if (ObjectUtils.isNotEmpty(oldPoint) && ObjectUtils.isNotEmpty(oldPoint.getAvailablePoints())
                && oldPoint.getAvailablePoints().intValue() != 0) {
            //旧账户做个扣减的操作
            MemberPointsChangeVo oldChangeVo = new MemberPointsChangeVo()
                    .setChangeType(PointSendTypeEnum.AUTOMATIC.getCode())
                    .setId(oldPoint.getId())
                    .setPoint(BigDecimal.valueOf(oldPoint.getAvailablePoints().intValue()).negate().intValue())
                    .setRemark("合并账号旧账号转出积分")
                    .setType(PointChangeValueEnums.REDUCE.value());
            this.deduceTenantPoints(oldChangeVo, PointRecordEnums.ACCOUNT_CONSOLIDATION);
            //新账号做个增加积分操作
            MemberPointsChangeVo changeVo = new MemberPointsChangeVo()
                    .setChangeType(PointSendTypeEnum.AUTOMATIC.getCode())
                    .setId(point.getId())
                    .setPoint(oldPoint.getAvailablePoints().intValue())
                    .setRemark("合并账号新账号转入积分")
                    .setType(PointChangeValueEnums.ADD.value());
            this.changeTenantPoints(changeVo, PointRecordEnums.ACCOUNT_CONSOLIDATION);
        }

    }

    public void sendMailCode(String mobile) {
        SmsCodeSendReqDTO dto = new SmsCodeSendReqDTO().setCreateIp(getClientIP()).setMobile(mobile).setScene(SmsSceneEnum.MEMBER_POINTS_MALL.getScene());
        CommonResult<Boolean> result = smsCodeApi.sendSmsCode(dto);
        if (!result.isSuccess()) {
            throw new ServiceException(GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR.getCode(), "验证码发送失败");
        }
    }

    public void validateMailCode(SmsCodeMallReqDTO reqVO) {
        try {
            SmsCodeUseReqDTO dto = new SmsCodeUseReqDTO();
            dto.setCode(reqVO.getCode());
            dto.setMobile(reqVO.getMobile());
            dto.setScene(SmsSceneEnum.MEMBER_POINTS_MALL.getScene());
            dto.setUsedIp(getClientIP());
            CommonResult<Boolean> validData = smsCodeApi.useSmsCode(dto);
            if (validData.isSuccess()) {
                boolean validFlag = ObjectUtils.isNotEmpty(validData.getData()) ? validData.getData().booleanValue() : false;
                if (!validFlag) {
                    throw new ServiceException(GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR.getCode(), "验证码不正确");
                }
            } else {
                throw new ServiceException(GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR.getCode(), "验证码不正确");
            }
        } catch (Exception e) {
            throw new ServiceException(GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR.getCode(), "验证码不正确");
        }
    }
}

